/** */
package co.com.umobile.service.impl;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Calendar;
import java.util.TimeZone;

import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import co.com.umobile.R;
import co.com.umobile.application.GlobalState;
import co.com.umobile.common.ResponseCodes;
import co.com.umobile.domain.ServiceResponse;
import co.com.umobile.domain.User;
import co.com.umobile.gui.LoginActivity;
import co.com.umobile.gui.MenuActivity;
import co.com.umobile.network.CheckConnection;
import co.com.umobile.service.LoginExtService;
import co.com.umobile.service.LoginServices;
import co.com.umobile.service.SessionServices;

/**
 * Class that implement the services of the LoginServices interface.
 * @author sergiogranada
 * 
 */
/**
 * @author Administrador
 * 
 */
public class LoginServicesImpl implements LoginServices {

	/** globalState is used to transfer data to other activity. */
	private GlobalState globalState;

	/** the context app. */
	private Context context;

	/** the login activity. */
	private LoginActivity loginActivity;

	/** the session services. */
	private SessionServices sessionServices;

	/*
	 * (non-Javadoc)
	 * 
	 * @see co.com.psl.ssfmobile.asesor.common.util.services.login.LoginServices#authenticateuser(co.com.psl.ssfmobile
	 * .asesor .gui.LoginActivity, java.lang.String, java.lang.String)
	 */
	public void authenticateuser(LoginActivity loginActivity, String userName, String password) {
		this.loginActivity = loginActivity;
		setGlobalState(loginActivity);

		if (!globalState.isLoginDisable()) {
			if (CheckConnection.isConnected(loginActivity.getApplicationContext())) {
				authenticateUserOnline(userName, password);
			}

		} else {
			globalState.setLoginDisable(false);
			clearPasswordField();
			return;
		}

	}

	/**
	 * returns the last valid user session.
	 * 
	 * @return User.
	 */
	public User getLastUserSession() {
		return sessionServices.getLastUserSession();
	}

	// SSFMOBILE-138
	/**
	 * authenticates the user in online mode.
	 * 
	 * @param userName
	 *            user identifier.
	 * @param password
	 *            key identifier of the user.
	 */
	private void authenticateUserOnline(String userName, String password) {

		try {

			User userSession = globalState.getLastUserSession();

			/* creates a date with this format: yyyy/MM/dd HH:mm:ss */
			Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

			/* this string contains the date and time with its custom format */
			String dateTimeString = String.valueOf(calendar.getTimeInMillis());

			JSONObject jsonObject = new JSONObject();

			jsonObject.put("usr", userName);
			jsonObject.put("pwd", password);
			jsonObject.put("ut", "1");
			// jsonObject.put("pwd", PslCrypter.encrypt(password));
			jsonObject.put("da", dateTimeString);

			LoginExtService authenticationExtService = new LoginExtService();
			ServiceResponse serviceResponse = authenticationExtService.authenticate(jsonObject, userName, password,
					globalState, loginActivity.getApplicationContext());

			if (globalState.isLoginDisable()) {
				globalState.setLoginDisable(false);
				clearPasswordField();
				return;
			}

			if (serviceResponse == null || serviceResponse.getCode() == null) {
				showLoginDialogMessage(loginActivity.getApplicationContext().getResources()
						.getString(R.string.login_authentication_error));
				clearPasswordField();
				return;
			}

			if (serviceResponse.getCode().equals(ResponseCodes.SUCCESSFUL)) {
				// actualiza los intentos de conexion offline a cero.

				User userSessionResponse = serviceResponse.getUserSession();

				User lastUserSession = globalState.getSessionServices().getLastUserSession();

				if (lastUserSession == null || userSessionResponse.getUserCode().equals(lastUserSession.getUserCode())) {
					globalState.getSessionServices().updateUser(serviceResponse.getUserSession(), context);
					globalState.setLastUserSession(serviceResponse.getUserSession());
					 loginActivity.onAuthenticationResult();
					clearPasswordField();
					showHomeScreen();
				} else {
					showLoginDialogMessage(loginActivity.getApplicationContext().getResources()
							.getString(R.string.single_user_message));
					clearPasswordField();
				}

			} else {
				if (globalState.isLoginDisable()) {
					globalState.setLoginDisable(false);
					clearPasswordField();
					return;
				}
				showLoginDialogMessage(serviceResponse.getDescription() + "  "
						+ loginActivity.getApplicationContext().getResources().getString(R.string.code_label)
						+ serviceResponse.getCode());
				clearPasswordField();
			}

		} catch (Exception e) {

			if (globalState.isLoginDisable()) {
				globalState.setLoginDisable(false);
				clearPasswordField();
				return;
			}
			clearPasswordField();
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			pw.flush();
			String cause = "";

			if (e.getCause() != null) {
				cause = e.getCause().toString();
			}
			showLoginDialogMessageException(cause + " " + sw.toString());

		}

	}

	/**
	 * clears the login password field.
	 */
	private void clearPasswordField() {
		loginActivity.runOnUiThread(new Runnable() {

			public void run() {
				loginActivity.clearPasswordField();
			}
		});
	}

	/**
	 * shows the home screen.
	 */
	private void showHomeScreen() {

		// if (globalState != null && globalState.getUserSession() != null) {
		// configurationServices.configureBugsUsername(globalState.getUserSession().getUserName());
		// }
		Intent intent = new Intent(loginActivity, MenuActivity.class);
		loginActivity.startActivity(intent);
	}

	/**
	 * Shows the dialog message.
	 * 
	 * @param message
	 *            Message to show.
	 */
	private void showLoginDialogMessageException(final String message) {
		// loginActivity.runOnUiThread(new Runnable() {
		//
		// public void run() {
		// loginActivity.showLoginAlertDialogMessage(message);
		// }
		// });
	}

	/**
	 * shows a dialog message in the login screen.
	 * 
	 * @param message
	 *            message.
	 */
	private void showLoginDialogMessage(final String message) {

		loginActivity.runOnUiThread(new Runnable() {

			public void run() {
				loginActivity.showDialog(message);
			}
		});
	}

	/**
	 * sets the global state.
	 * 
	 * @param activity
	 *            activity.
	 */
	private void setGlobalState(Activity activity) {
		globalState = (GlobalState) activity.getApplication();
		context = activity.getApplicationContext();
	}

}
